package magicboard.classifier.direction
{

	import magicboard.classifier.Classifier;
	import magicboard.classifier.patterndb.PatternDB;
	import magicboard.geometry.Vector;
	import magicboard.model.InkStroke;
	
	/**
	 */
	public class DirectionClassifier implements Classifier
	{
		// --------------------------------------------------------------------------------------------
		public function DirectionClassifier(){
			
			initPatterns();
		}
		
		// --------------------------------------------------------------------------------------------
		/**
		 * Decodes input stroke as series of directions based on vectors.
		 * Directions and the codes:
		 *                G
		 *              F   H
		 *            E       A
		 *              D   B
		 *                C
		 * 
		 * @return Stroke with recognized type
		 */
		public function classify(input:InkStroke):String{	
			
			var pattern:DirectionPattern;
			var gestures:String;
			
			gestures = extractDirections(input.simplifiedPoints);
			
			trace("Input : " + gestures);
			pattern = findPattern(gestures);
			
			if(pattern)
				return pattern.name;
				
	  	return "Unknown";
		}
		
		// --------------------------------------------------------------------------------------------
		/**
		 * WARNING:
		 * The x coord in flash is upside down. So for character 1 intstead of getting BG
		 * this funcrion will return HC
		 */ 
		private function extractDirections(points:Array):String{
			
			var dirTemp:String = "";
			var A:String = "A";
			var i:int;
			
			for(i = 0; i < points.length-1; i++){
			
				var v:Vector = Vector.points2Vector(points[i], points[i+1]);
				var angle:Number = v.angle + 1/8*Math.PI;	
				var dir:int = Math.floor( angle/(1/4*Math.PI) );

				if(dir == 8)
					dir = 0;
				dirTemp += String.fromCharCode( A.charCodeAt(0)+dir );
								
			}
			
			return dirTemp;
		}
		
		// --------------------------------------------------------------------------------------------
		/**
		 * Read patters from database
		 */
		private function initPatterns():void{
			
			_patterns = new Array();
			for( var key:String in PatternDB.references ){
				for each( var ref:String in PatternDB.references[key] ){
	  			var stroke:InkStroke = new InkStroke();
	  			var pattern:DirectionPattern;
	  			var dir:String; 
	  			
	  			stroke.loadFromString(key + ":" + ref);
	  			dir = extractDirections(stroke.simplifiedPoints);
	  			trace( key + " -> " + dir );
	  			pattern = new DirectionPattern( key, dir );
	  			_patterns.push( pattern );
	  		}
			}
		}
		
		// --------------------------------------------------------------------------------------------
		/**
		 * Read patters from database
		 */
		private function findPattern(gestures:String):DirectionPattern{
			
			for each(var pattern:DirectionPattern in _patterns){
				if( pattern.compare(gestures) )
					return pattern;
			}
			
			return null;
		}
		
		
		// --------------------------------------------------------------------------------------------
		// Private members
		private var _patterns:Array;
	}
}